#if defined mystreamer_inc
#endscript
#endif
#define mystreamer_inc

#include <a_samp>

#tryinclude num_players

#if !defined MAX_STREAM_OBJECTS
#define MAX_STREAM_OBJECTS 50
#endif

#define getox(%0) (streamer_objects[%0][e_x_ox] << 16)
#define getoy(%0) (streamer_objects[%0][e_y_oy] << 16)
#define getoz(%0) (streamer_objects[%0][e_z_oz] << 16)

#define getx(%0) (streamer_objects[%0][e_x_ox] & 0xFFFF)
#define gety(%0) (streamer_objects[%0][e_y_oy] & 0xFFFF)
#define getz(%0) (streamer_objects[%0][e_z_oz] & 0xFFFF)

enum objstruct
{
	e_modelid,
	e_x_ox,
	e_y_oy,
	e_z_oz,
	/*Float:e_ox, // offsets
	Float:e_oy,
	Float:e_oz,
	Float:e_ow,*/
	e_rx, // rotating
	e_ry,
	e_rz,
	e_objectid[MAX_PLAYERS] //
};

static streamer_objects[MAX_STREAM_OBJECTS][objstruct];

static object_count = -1;

forward StreamObjects();

public StreamObjects()
{
	// Comment the line below if you're not using gActivePlayers variable.
	//if(!gActivePlayers) return false;
	new Float:xx, Float:yy, Float:zz;
	for(new playerid=0; playerid<MAX_PLAYERS; playerid++) if(GetPlayerPos(playerid, xx, yy, zz))
	{
		StreamRangeObjects(xx, yy, zz, 350.0, playerid);
	}
	return true;
}

StreamRangeObjects(Float:x, Float:y, Float:z, Float:range, extra)
{
	new offset = (x * x + y * y + z * z) * 10;
	new const sqrange = range * range * 10;
	for(new j = 0; j <= object_count; ++j)
	{
		// Calculate the distance to the object.
		offset = offset + streamer_objects[j][e_ow] + x * getox(j) +
		y * getoy(j) + z * getoz(j);
		// We now have the SQUARED distance to this object.
		if (offset < sqrange)
		{
			ShowStreamObjectForPlayer(j, extra);
		}
		else
		{
			HideStreamObjectForPlayer(j, extra);
		}
	}
}


ShowStreamObjectForPlayer(sobjectid, playerid)
{
	if(streamer_objects[sobjectid][e_objectid] == 0)
	{
		streamer_objects[sobjectid][e_objectid] =
			CreatePlayerObject(playerid, streamer_objects[sobjectid][e_modelid],
				getx(sobjectid)/10, gety(sobjectid)/10, getz(sobjectid)/10,
				streamer_objects[sobjectid][e_rx]/10, streamer_objects[sobjectid][e_ry]/10, streamer_objects[sobjectid][e_rz]/10);
		if(streamer_objects[sobjectid][e_objectid] == INVALID_OBJECT_ID)
			streamer_objects[sobjectid][e_objectid] = 0;
		return true;
	}
	else
		return false;
}


HideStreamObjectForPlayer(sobjectid, playerid)
{
	if(streamer_objects[sobjectid][e_objectid] != 0)
	{
		DestroyPlayerObject(playerid, streamer_objects[sobjectid][e_objectid]);
		streamer_objects[sobjectid][e_objectid] = 0;
		return true;
	}
	else
		return false;
}

stock CreatemyStreamObject(modelid, Float:x, Float:y, Float:z, Float:rx, Float:ry, Float:rz)
{
	new ox, oy, oz,
		nx, ny, nz;
	if(object_count >= MAX_STREAM_OBJECTS) return(-1);
	// Get the offset from the last object.
	if (object_count == -1)
	{
		ox = 0.0;
		oy = 0.0;
		oz = 0.0;
	}
	else
	{
		ox = streamer_objects[object_count][e_x];
		oy = streamer_objects[object_count][e_y];
		oz = streamer_objects[object_count][e_z];
	}
	new
		dx = ox - floatround(x * 10),
		dy = oy - floatround(y * 10),
		dz = oz - floatround(z * 10);
	++object_count;
	// Store the offsets.
	streamer_objects[object_count][e_x_ox] += (2 * dx) << 16;
	streamer_objects[object_count][e_y_oy] += (2 * dy) << 16;
	streamer_objects[object_count][e_z_oz] += (2 * dz) << 16;
	// Calculate the main constant.
	streamer_objects[object_count][e_ow] =
		(dx * dx + dy * dy + dz * dz) - 2 *
		(ox * dx + oy * dy + oz * dz);
	// Store the other data.
	streamer_objects[object_count][e_x] = x;
	streamer_objects[object_count][e_y] = y;
	streamer_objects[object_count][e_z] = z;
	streamer_objects[object_count][e_rx] = rx;
	streamer_objects[object_count][e_ry] = ry;
	streamer_objects[object_count][e_rz] = rz;
	streamer_objects[object_count][e_modelid] = modelid;
	return object_count;
}

/*
mystream_ongamemodeinit()
{
	//for(new i=0; i<MAX_PLAYERS; i++)
		//e_objectid
}*/




